﻿

using System;
using System.Collections.Generic;

public static class EventCenter
{
    private static Dictionary<EventType, Delegate> m_EventTable = new Dictionary<EventType, Delegate>();
    
    private static bool OnListenerAdd(EventType eventType, Delegate callback)
    {
        if (!m_EventTable.ContainsKey(eventType))
        {
            m_EventTable.Add(eventType, null);
            return false;
        }
        var d = m_EventTable[eventType];
        if (d != null && d.GetType() != callback.GetType())
        {
            throw new Exception($"事件类型与委托不匹配：Event={eventType}, Event Delegate Type ={d.GetType()}, Current Callback={callback.GetType()}");
        }
        return true;
    }

    private static bool OnlistenerRemove(EventType eventType, Delegate callback)
    {
        if (!m_EventTable.ContainsKey(eventType))
        {
            throw new Exception($"移除监听器错误: {eventType}");
        }
        var d = m_EventTable[eventType];
        if (d == null || d.GetType() != callback.GetType())
        {
            throw new Exception($"移除监听器错误2: {eventType}");
        }
        return true;
    }

    public static void AddListener(EventType eventType, CallBack callback)
    {
        OnListenerAdd(eventType, callback);
        m_EventTable[eventType] = (CallBack)m_EventTable[eventType] + callback;

    }

    public static void RemoveListener(EventType eventType, CallBack callback)
    {
        OnlistenerRemove(eventType, callback);
        m_EventTable[eventType] = (CallBack)m_EventTable[eventType] - callback;
    }

    public static void Broadcast(EventType eventType)
    {
        Delegate d;
        if (m_EventTable.TryGetValue(eventType, out d))
        {
            CallBack callback = d as CallBack;
            if (null != callback)
            {
                callback();
            }
        }

    }

    public static void AddListener<T>(EventType eventType, CallBack<T> callback)
    {
        OnListenerAdd(eventType, callback);
        m_EventTable[eventType] = (CallBack<T>)m_EventTable[eventType] + callback;

    }

    public static void RemoveListener<T>(EventType eventType, CallBack<T> callback)
    {
        OnlistenerRemove(eventType, callback);
        m_EventTable[eventType] = (CallBack<T>)m_EventTable[eventType] - callback;
    }

    public static void Broadcast<T>(EventType eventType, T arg)
    {
        Delegate d;
        if (m_EventTable.TryGetValue(eventType, out d))
        {
            var callback = d as CallBack<T>;
            if (null != callback)
            {
                callback(arg);
            }
        }

    }
}
